<?php


namespace App\Models\CacheModel;


use app\aliyun\controller\AliyunVOD;
use App\Models\CacheModel\zl8\Zl8AstrChatBusyDateRecord;
use App\Models\CacheModel\zl8\Zl8AstrChatBusyRecord;
use App\Models\CacheModel\zlcr3\Zlcr3ConsultAccount;
use app\common\lib\Util;
use App\Models\Api\BaseCache;
use app\zyhsapi\model\good_rtc_live\ZyhsGoodRtcLiveMedia;
use app\zyhsapi\model\ZyhsConfig;
use think\Cache;
use think\Config;
use think\Db;
use think\Log;
use AstroTool\Cache\CacheManage;

class ZlcrAstr extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.zlcr_astr';
    public $cacheModel = 'astr_admin.astr';
    protected $astrTagCacheModel = 'astr_admin.astr_tag';
    protected $cacheIdKey = 'id';

    protected $underwayTaskCacheModel = 'astr_admin.astr_underway_task';

    // public $astrLevelProportionOld = [   //  旧分成比例
    //     0 => 0.2,   // 专业占星师,1=>高级占星师,2=>大师占星师,3=>至臻占星师
    //     1 => 0.3,   // 高级占星师 30%
    //     2 => 0.4,   // 大师占星师 40%
    //     3 => 0.5,   // 至臻占星师 50%
    // ];
    public $astrLevelProportion = [
        0 => 0.1,   // 专业占星师,1=>高级占星师,2=>大师占星师,3=>至臻占星师
        1 => 0.15,   // 高级占星师 15%
        2 => 0.18,   // 大师占星师 18%
        3 => 0.2,   // 至臻占星师 20%
    ];

    public $astrTypeLevelKeyName = [
        1 => [  // 问答-星盘
            'level' => 'astro2_level',
            'score' => 'astro2_grade',
        ],
        2 => [  // 问答-骰子
            'level' => 'dice_level',
            'score' => 'dice_grade',
        ],
        3 => [  // 问答-塔罗
            'level' => 'tarot_level',
            'score' => 'tarot_grade',
        ],
    ];

    public $astrLevelName = [
        0 => '专业占星师',
        1 => '高级占星师',
        2 => '大师占星师',
        3 => '至臻占星师',
    ];

    public $astrLevelName2 = [
        1 => [  // 定制报告
            0 => '专业占星师',
            1 => '高级占星师',
            2 => '大师占星师',
            3 => '至臻占星师',
        ],
        2 => [  // 问答-星盘
            0 => '专业咨询师',
            1 => '专业咨询师',
            2 => '高级咨询师',
            3 => '至臻咨询师',
        ],
        3 => [  // 问答-骰子
            0 => '专业咨询师',
            1 => '专业咨询师',
            2 => '高级咨询师',
            3 => '至臻咨询师',
        ],
        4 => [  // 问答-塔罗
            0 => '专业咨询师',
            1 => '专业咨询师',
            2 => '高级咨询师',
            3 => '至臻咨询师',
        ],
    ];

    /**
     * 获取占星师 问答问题 分成比例
     * @param int $receivingTime 接单时间
     * @param int $questionType 问答 问题类型  1=>占星 2=>骰子 3=>塔罗
     * @param int $astrLevel 咨询师 当前问答等级
     * @return float
     * @throws \Exception
     */
    public function getAstrQuestionAnswerProportion(int $receivingTime, int $questionType, int $astrLevel)
    {
        $questionAnswerConfig = (new AppConfig())->configInfo('question_answer');    // 获取问答配置
        // 测试环境  提前进入 新的分成比例模式  1=>强制进入新分成比例模式 0=>正常逻辑
        $test = $questionAnswerConfig && isset($questionAnswerConfig['proportion_test']) ? (int)$questionAnswerConfig['proportion_test'] : 0;

        if ($receivingTime > 1651334400 || $test === 1)    // 1651334400 => 2022-05-01 00:00:00
        {   // 2022年5月1号之后 分成比例
            $astrQuestionAnswerProportion = [
                1 => [  // 星盘
                    1 => 0.2,
                    2 => 0.25,
                    3 => 0.35,
                ],
                2 => [  // 骰子
                    1 => 0.25,
                    2 => 0.25,
                    3 => 0.25,
                ],
                3 => [  // 塔罗
                    1 => 0.2,
                    2 => 0.25,
                    3 => 0.35,
                ],
            ];
        } else
        {   // 2022年5月1号之前 分成比例
            $astrQuestionAnswerProportion = [
                1 => [  // 星盘
                    1 => 0.4,
                    2 => 0.45,
                    3 => 0.5,
                ],
                2 => [  // 骰子
                    1 => 0.5,
                    2 => 0.5,
                    3 => 0.5,
                ],
                3 => [  // 塔罗
                    1 => 0.4,
                    2 => 0.45,
                    3 => 0.5,
                ],
            ];
        }

        return $astrQuestionAnswerProportion[$questionType][$astrLevel];
    }

    /**
     * 获取占星师 问答追问 分成比例
     * @param int $receivingTime 接单时间
     * @param int $questionType 问答问题类型 1=>占星 2=>骰子 3=>塔罗
     * @param int $astrLevel 咨询师 当前问答等级
     * @return float
     * @throws \Exception
     */
    public function getAstrQuestionAnswerAddQuestionProportion(int $receivingTime, int $questionType, int $astrLevel)
    {
        $questionAnswerConfig = (new AppConfig())->configInfo('question_answer');    // 获取问答配置
        // 测试环境  提前进入 新的分成比例模式  1=>强制进入新分成比例模式 0=>正常逻辑
        $test = $questionAnswerConfig && isset($questionAnswerConfig['proportion_test']) ? (int)$questionAnswerConfig['proportion_test'] : 0;

        if ($receivingTime > 1651334400 || $test === 1)    // 1651334400 => 2022-05-01 00:00:00
        {   // 2022年5月1号之后 分成比例
            $astrQuestionAnswerAddQuestionProportion = [
                1 => [  // 星盘
                    1 => 0.5,
                    2 => 0.5,
                    3 => 0.5,
                ],
                2 => [  // 骰子
                    1 => 0.5,
                    2 => 0.5,
                    3 => 0.5,
                ],
                3 => [  // 塔罗
                    1 => 0.5,
                    2 => 0.5,
                    3 => 0.5,
                ],
            ];
        } else
        {   // 2022年5月1号之前 分成比例
            $astrQuestionAnswerAddQuestionProportion = [
                1 => [  // 星盘
                    1 => 0.6,
                    2 => 0.6,
                    3 => 0.6,
                ],
                2 => [  // 骰子
                    1 => 0.6,
                    2 => 0.6,
                    3 => 0.6,
                ],
                3 => [  // 塔罗
                    1 => 0.6,
                    2 => 0.6,
                    3 => 0.6,
                ],
            ];
        }

        return $astrQuestionAnswerAddQuestionProportion[$questionType][$astrLevel];
    }

    /**
     * 更新数据
     * @param $astrId
     * @param $where
     * @param $data
     * @return bool
     */
    public function UpdateData($astrId, $where, $data)
    {
        try
        {
            $this->where($where)->update($data);
            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $astrId)->setCache($data);
            if (isset($data['custom_report_status']))
            {
                if ($data['custom_report_status'])
                {
                    CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('astr_ids', 1)->listAdd([$astrId => $astrId], 0, 'astr_ids');
                } else
                {
                    CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('astr_ids', 1)->delJudge([$astrId], 'astr_ids');
                }
            }
        }
        catch (\Exception $e)
        {
            Log::write('占星师信息更新失败:' . $e->getMessage() . '失败文件信息：【' . $e->getFile() . ':' . $e->getLine() . '】', 'error', true);
            return false;
        }
        return true;
    }

    /**
     * 获取前五的占星师信息·
     * @param int $length 截取长度
     * @param array $field 字段
     * @return array
     * @throws \Exception
     */
    public function getAstrInfoFromCache($length, $field)
    {
        $ids = CacheManage::getInstance()->setCacheConfig($this->cacheModel, 0)->ZsGetIocData('list', function ()
        {
            return $this->getAstrIdFromDms();
        }, true);
        $ids = array_slice(array_keys($ids), 0, $length);
        return $this->batchGetInfoByIds($ids, $field);
    }

    /**
     * 获取前10的占星师id
     * @return array
     */
    public function getAstrIdFromDms()
    {
        //获取账号正常，可接单且最新评价在三星及以上的占星师
        try
        {
            $data = Db::query("SELECT a.id,c.time FROM `wechat_backup_07_18_14_43_00`.`zlcr_astr` as a inner join (SELECT substring_index(group_concat(create_time order by create_time ASC),', ',1) time,astr_id,level from `wechat_backup_07_18_14_43_00`.`zlcr_custom_report_question_comment` group by qid) as c on a.id=c.astr_id where a.status=1 and a.check_status=40 and a.astr_type=1 and (c.level =3 or c.level > 3) group by a.id order by c.time DESC ");//获取最新评价三星及以上的占星师id

            $ids1 = [];
            foreach ($data as $key => $item)
            {
                $ids1[$item['id']] = $item['time'];
            }

            //获取虚拟占星师
            if (count($ids1) < 3)
            {
                $ids2 = $this->where(['status' => 1, 'astr_type' => 2])->order('last_reply_time', 'DESC')->limit(3)->column('id', 'id');
                $ids2 = array_flip_key_value($ids2);
                $ids = array_merge($ids1, $ids2);
            } else
            {
                $ids = $ids1;
            }
        }
        catch (\Exception $e)
        {
            $ids = [];
        }
        return $ids;
    }

    /**
     * 批量获取占星师标签信息
     * @param $id
     * @return array|false
     * @throws \Exception
     */
    public function getAstrTagInfo($id)
    {
        $tag = CacheManage::getInstance()->setCacheConfig($this->astrTagCacheModel, $id)
            ->getDataAndSet(function () use ($id)
            {
                try
                {
                    $tag_name = (new ZlcrCustomReportQuestionComment())
                        ->alias('c')
                        ->join('wechat_backup_07_18_14_43_00.zlcr_tag t', 'c.tid=t.id', 'inner')
                        ->where(['c.astr_id' => $id])
                        ->column('t.tag_name');
                    if (count($tag_name) > 3)
                    {
                        $tag_name = array_slice($tag_name, 0, 3);
                    }
                    $tag = $tag_name ? implode(' | ', $tag_name) : '';
                }
                catch (\Exception $e)
                {
                    $tag = '';
                }
                return $tag;
            });
        return $tag;
    }

    /**
     * 重写数据时获取数据
     * @param $ids
     * @param $type
     * @param $sortType
     * @return array|false|string|void
     */
    public function getInfoByIdsInData($ids, $type, $sortType)
    {
        try
        {
            $data = $this->whereIn('id', $ids)->column('uid,password,tel,salt,token,token_expire,nickname,avatar,status,check_status,last_reply_time,extend,sort,create_time,astr_type,astr_level,astro_grade,astro2_level,astro2_grade,dice_level,dice_grade,tarot_level,tarot_grade,answer_pause_time,answer_num,rating,subscribe,modify_password,password_reset_at,pause_time,auth_status,custom_report_status,team_id', 'id');
        }
        catch (\Exception $e)
        {
            $data = [];
        }

        return $data;
    }

    public function batchGetInfoByIds($cids, $field = [])
    {
        $resData = parent::batchGetInfoByIds($cids, $field);

        foreach ($resData as $cid => $dataItem)
        {
            $resData[$cid] = arrayKeyData2int($dataItem, ['uid', 'token_expire', 'status', 'check_status', 'last_reply_time', 'sort', 'create_time', 'astr_type', 'astr_level', 'astro_grade', 'astro2_level', 'astro2_grade', 'dice_level', 'dice_grade', 'tarot_level', 'tarot_grade', 'answer_pause_time', 'answer_num', 'subscribe', 'modify_password', 'password_reset_at', 'pause_time', 'custom_report_status', 'team_id']);

            if (isset($dataItem['auth_status']))
            {
                $resData[$cid]['auth_status'] = $dataItem['auth_status'] ? json_decode($dataItem['auth_status'], true) : [
                    'custom_report' => 0,
                    'question_answer_astr' => 0,
                    'question_answer_dice' => 0,
                    'question_answer_tarot' => 0,
                ];
            }
            if (isset($dataItem['extend']))
            {
                $dataItem['extend'] = $dataItem['extend'] ? json_decode($dataItem['extend'], true) : [];
                $resData[$cid]['extend'] = $dataItem['extend'];
                //简介
                $resData[$cid]['qualification'] = $dataItem['extend']['qualification'] ?? ['content' => '', 'pic_list' => []];
                //营业介绍
                $resData[$cid]['work_intro'] = $dataItem['extend']['work_intro'] ?? '';
                //服务时间
                $resData[$cid]['service_time'] = $dataItem['extend']['service_time'] ?? '';
                //音视频介绍
                $resData[$cid]['media_intro'] = $dataItem['extend']['media_intro'] ?? ['type' => 0, 'img' => '', 'url' => '', 'duration' => 0];
            }
        }

        return $resData;
    }

    /**
     * 获取进行中的任务
     * @param int $astrId
     * @return array
     * @throws \Exception
     */
    public function getUnderwayTask(int $astrId): array
    {
        $qidsData = CacheManage::getInstance()
            ->setCacheConfig($this->underwayTaskCacheModel, $astrId)
            ->setPage(-1)
            ->getListPageDataIds(function ($isCache = true, $sortType = 'desc') use ($astrId)
            {
                try
                {
                    $qids = $this->table('wechat_backup_07_18_14_43_00.zlcr_custom_report_question')
                        ->where('astr_id', $astrId)
                        ->whereIn('status', [3, 4, 13])  // 3=>问题待解答 4=>解答待审核 5=>已完成待评价 6=>已评价待审核 12=>占星师超时未完成失效 13=>问题待解答（答案审核未通过）
                        ->order('id desc')
                        ->column('id');
                    $idData = [];

                    foreach ($qids as $qid)
                    {
                        $idData[$qid] = ['id' => $qid];
                    }
                }
                catch (\Exception $e)
                {
                    $idData = [];
                }

                return $idData;
            }, 'id', 0);

        return $qidsData['data'] ? array_keys($qidsData['data']) : [];
    }

    /**
     * 获取旧的 进行中的任务
     * @param int $astrId
     * @return array
     */
    public function getOldUnderwayTask(int $astrId)
    {
        $qids = Cache::get('astr_admin:astr_old_underway_tasks:' . $astrId, []);

        return $qids ?: [];
    }

    /**
     * 设置旧的 进行中的任务
     * @param int $astrId
     * @param array $qids
     */
    public function setOldUnderwayTask(int $astrId, array $qids)
    {
        Cache::set('astr_admin:astr_old_underway_tasks:' . $astrId, $qids, 86400);
    }

    /**
     *  添加进行中的任务
     * @param int $astrId
     * @param int $qid
     * @throws \Exception
     */
    public function underwayTaskAdd(int $astrId, int $qid): void
    {
        CacheManage::getInstance()
            ->setCacheConfig($this->underwayTaskCacheModel, $astrId)
            ->listAdd([$qid => $qid]);
    }

    /**
     * 删除进行中的任务
     * @param int $astrId
     * @param array $qids
     * @throws \Exception
     */
    public function underwayTaskDel(int $astrId, array $qids): void
    {
        $cacheModel = CacheManage::getInstance()->setCacheConfig($this->underwayTaskCacheModel, $astrId);
        foreach ($qids as $rmqId)
        {
            $cacheModel->delJudge($rmqId, 'list');
        }
    }

    /**
     * 更新占星师能力分 及 好评率
     * @param int $astrId 占星师ID
     * @param $qid 问题ID
     * @param int $changeGrade 更新能力值
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function changeAstrGrade(int $astrId, $qid, int $changeGrade)
    {
        try
        {
            $time = time();
            $astrInfo = $this->getInfoById($astrId, ['astro_grade', 'astr_level', 'tel']);
            // 更新后的能力值
            $resGrade = $astrInfo['astro_grade'] + $changeGrade; // 最终能力者
            // 计算占星师好评率
            $rating = (new ZlcrCustomReportQuestionComment())->getRating($astrId);
            // 判断占星师等级是否变更
            $astrLevel = $this->getAstrLevelByGrade($resGrade);
            $where = ['astro_grade' => $resGrade, 'rating' => (float)$rating, 'update_time' => $time];
            if ($astrLevel != $astrInfo['astr_level'])
            {
                $where['astr_level'] = $astrLevel;
                if ($astrLevel > $astrInfo['astr_level'])
                { // 发送 升级  消息
                    Util::sendYxSms([$astrInfo['tel']], $extend = '', 37767, [
                        'grade' => $resGrade,
                        'name' => $this->astrLevelName[$astrLevel],
                        'scale' => ($this->astrLevelProportion[$astrLevel] * 100) . "%（税前）",
                    ]);
                    (new ZlcrAstrMessage())->add($astrId, [
                        'status' => 0,
                        'is_read' => 0,
                        'astr_id' => $astrId,
                        'type' => 2, // 占星师违规消息
                        'title' => '进阶成功通知',
                        'content' => "恭喜您的占星师能力分到达{$resGrade}分，成功进阶至{$this->astrLevelName[$astrLevel]}，完成订单分成比例为" . ($this->astrLevelProportion[$astrLevel] * 100) . "%（税前）。",
                        'target' => '',
                        'link' => '',
                        'create_time' => time(),
                    ]);
                } else
                { // 降级
                }
            }
            // 更新用户能力分及好评率
            $this->save($where, ['id' => $astrId]);
            // 写 能力分更新日志
            (new ZlcrAstrGradeChangeRecode())->save([
                'astr_id' => $astrId,
                'qid' => $qid,
                'change' => $changeGrade,   // 变动能力值
                'astro_grade' => $resGrade, // 变动后能力值
                'type' => 1,
                'create_time' => $time,
            ]);
        }
        catch (\Exception $e)
        {
            Log::write("更新占星师能力分失败【astr_id:{$astrId},qid:{$qid}】;错误信息：「{$e->getMessage()}」;错误文件「{$e->getFile()}」;行数「{$e->getLine()}」", 'error', true);
        }
    }

    /**
     * 通过能力者获取占星师等级
     * @param int $astroGrade
     * @return int
     */
    public function getAstrLevelByGrade(int $astroGrade): int
    {
        switch (true)
        {
            case $astroGrade >= 1500:
                $level = 3;
                break;
            case $astroGrade >= 500:
                $level = 2;
                break;
            case $astroGrade >= 100:
                $level = 1;
                break;
            default:
                $level = 0;
        }

        return $level;
    }

    /**
     * 更新占星师能力分 行为
     * @param int $astrId 占星师ID
     * @param $qid // 问题ID
     * @param int $changeGrade 更新能力值
     * @param int $type 类型  1=>评论更新 2=>申述后更新 3=>提交超时 4=>订单超时 5=>完成订单
     * @param int $pauseTime 账号冻结 到期时间 时间戳
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function changeAstr(int $astrId, $qid, int $changeGrade, int $type, int $pauseTime)
    {
        try
        {
            $time = time();
            $astrInfo = $this->getInfoById($astrId, ['astro_grade', 'astr_level', 'tel']);
            // 更新后的能力值
            $resGrade = $astrInfo['astro_grade'] + $changeGrade;
            // 判断能力分 是否导致 占星师等级变化
            // 判断占星师等级是否变更
            $astrLevel = $this->getAstrLevelByGrade($resGrade);
            $where = ['astro_grade' => $resGrade, 'update_time' => $time];
            if ($astrLevel != $astrInfo['astr_level'])
            {
                $where['astr_level'] = $astrLevel;
                if ($astrLevel > $astrInfo['astr_level'])
                { // 发送 升级  消息
                    Util::sendYxSms([$astrInfo['tel']], $extend = '', 37767, [
                        'grade' => $resGrade,
                        'name' => $this->astrLevelName[$astrLevel],
                        'scale' => ($this->astrLevelProportion[$astrLevel] * 100) . "%（税前）",
                    ]);
                    (new ZlcrAstrMessage())->add($astrId, [
                        'status' => 0,
                        'is_read' => 0,
                        'astr_id' => $astrId,
                        'type' => 2, // 占星师违规消息
                        'title' => '进阶成功通知',
                        'content' => "恭喜您的占星师能力分到达{$resGrade}分，成功进阶至{$this->astrLevelName[$astrLevel]}，完成订单分成比例为" . ($this->astrLevelProportion[$astrLevel] * 100) . "%（税前）。",
                        'target' => '',
                        'link' => '',
                        'create_time' => time(),
                    ]);
                } else
                { // 降级
                }
            }
            if ($pauseTime > 0)
            { // 账号冻结
                $where['pause_time'] = $pauseTime;
            }
            // 更新用户能力分
            $this->save($where, ['id' => $astrId]);
            // 写 能力分更新日志
            (new ZlcrAstrGradeChangeRecode())->save([
                'astr_id' => $astrId,
                'qid' => $qid,
                'question_type' => 0,
                'change' => $changeGrade,   // 变动能力值
                'astro_grade' => $resGrade, // 变动后能力值
                'type' => $type,
                'create_time' => $time,
            ]);
        }
        catch (\Exception $e)
        {
            Log::write("更新占星师能力分失败【astr_id:{$astrId},qid:{$qid}】;错误信息：「{$e->getMessage()}」;错误文件「{$e->getFile()}」;行数「{$e->getLine()}」", 'error', true);
        }
    }

    /**
     * 更新 占星师 问答 能力分
     * @param int $astrId
     * @param $qid
     * @param int $changeGrade
     * @param int $levelType 1=>星盘   2=>骰子  3=>塔罗
     * @param int $type 类型  1=>评论更新 5=>完成订单 6=>提交3次审核失败 7=>每日接单并回复对应问答5单则+5分
     *        8=>任务超时回复-5分 9=>过去30天任务超时回复第2次-10分 10=>过去30天任务超时回复第3次-50分
     *        11=>追问回复超时 12=>30日内2次追问回复超时，额外扣除能力分，能力分-5分    13=>30日内3次追问回复超时，额外扣除能力分，能力分-10分；同时冻结接单资格
     * @param int $pauseTime
     * @throws \Exception
     */
    public function changeAstrScore(int $astrId, $qid, int $changeGrade, int $levelType, int $type, int $pauseTime)
    {
        if (!isset($this->astrTypeLevelKeyName[$levelType]))
        {
            return;
        }
        try
        {
            $time = time();
            $astrInfo = $this->getInfoById($astrId, [$this->astrTypeLevelKeyName[$levelType]['level'], $this->astrTypeLevelKeyName[$levelType]['score'], 'tel']);
            // 更新后的能力值
            $resGrade = $astrInfo[$this->astrTypeLevelKeyName[$levelType]['score']] + $changeGrade;
            // 判断能力分 是否导致 占星师等级变化
            // 判断 问答 等级是否变更
            $qaLevel = $this->getQuestionAnswerLevel($resGrade);
            $updateData = [$this->astrTypeLevelKeyName[$levelType]['score'] => $resGrade, 'update_time' => $time];
            if ($qaLevel != abs($astrInfo[$this->astrTypeLevelKeyName[$levelType]['level']]))
            { // 等级变动
                if ($astrInfo[$this->astrTypeLevelKeyName[$levelType]['level']] > 0)
                {
                    $updateData[$this->astrTypeLevelKeyName[$levelType]['level']] = $qaLevel;
                } else
                {
                    $updateData[$this->astrTypeLevelKeyName[$levelType]['level']] = $qaLevel * -1;
                }
                if (in_array($levelType, [1, 3], true))
                {   // 星盘和塔罗 发送消息
                    if ($qaLevel > $astrInfo[$this->astrTypeLevelKeyName[$levelType]['level']])
                    { // 发送 升级  消息
                        $qname = $levelType === 1 ? '占星' : '塔罗';
                        Util::sendHySms([$astrInfo['tel']], $extend = '', 52476, [
                            'type_name' => $qname,
                            'name' => $this->astrLevelName2[$levelType + 1][$qaLevel],
                            'scale' => ($this->getAstrQuestionAnswerProportion($time, $levelType, $qaLevel) * 100) . "%税前",
                        ]);
                        (new ZlcrAstrMessage())->add($astrId, [
                            'status' => 0,
                            'is_read' => 0,
                            'astr_id' => $astrId,
                            'type' => 2, // 占星师违规消息
                            'title' => '进阶成功通知',
                            'content' => "你的问答-{$qname}已升级为{$this->astrLevelName2[$levelType+1][$qaLevel]}，问题回答收益分成已提升至" . ($this->getAstrQuestionAnswerProportion($time, $levelType, $qaLevel) * 100) . "%（税前），继续努力！",
                            'target' => '',
                            'link' => '',
                            'create_time' => time(),
                        ]);
                    } else
                    { // 降级
                    }
                }
            }
            if ($pauseTime > 0)
            { // 账号冻结
                $updateData['answer_pause_time'] = $pauseTime;
            }
            if (in_array($type, [10, 13], true))
            {   // 任务超时回复3次 冻结账号 该类型接单资格
                if (isset($updateData[$this->astrTypeLevelKeyName[$levelType]['level']]))
                {
                    $updateData[$this->astrTypeLevelKeyName[$levelType]['level']] = $updateData[$this->astrTypeLevelKeyName[$levelType]['level']] > 0 ? $updateData[$this->astrTypeLevelKeyName[$levelType]['level']] * -1 : $updateData[$this->astrTypeLevelKeyName[$levelType]['level']];
                } else
                {
                    $updateData[$this->astrTypeLevelKeyName[$levelType]['level']] = $astrInfo[$this->astrTypeLevelKeyName[$levelType]['level']] > 0 ? $astrInfo[$this->astrTypeLevelKeyName[$levelType]['level']] * -1 : $astrInfo[$this->astrTypeLevelKeyName[$levelType]['level']];
                }
            }
            // 更新用户能力分
            $this->save($updateData, ['id' => $astrId]);
            // 写 能力分更新日志
            (new ZlcrAstrGradeChangeRecode())->save([
                'astr_id' => $astrId,
                'qid' => $qid,
                'question_type' => $levelType,
                'change' => $changeGrade,   // 变动能力值
                'astro_grade' => $resGrade, // 变动后能力值
                'type' => $type,
                'create_time' => $time,
            ]);
        }
        catch (\Exception $e)
        {
            Log::write("更新问答占星师能力分失败【astr_id:{$astrId},qid:{$qid}】;错误信息：「{$e->getMessage()}」;错误文件「{$e->getFile()}」;行数「{$e->getLine()}」", 'error', true);
        }
    }

    /**
     * 获取问答等级
     * @param int $score
     * @return int
     */
    public function getQuestionAnswerLevel(int $score)
    {
        switch (true)
        {
            case $score >= 800:
                $level = 3;
                break;
            case $score >= 301:
                $level = 2;
                break;
            case $score >= 0:
                $level = 1;
                break;
            default:
                $level = 0;
        }

        return $level;
    }

    /**
     * 获取 咨询师IDs
     * @return array
     * @throws \Exception
     */
    public function getConsultAstroIds()
    {
        $resData = (new Zlcr3ConsultAccount())->getChatConsultIds(0, -1);
        return $resData['data'];
    }

    /**
     * 主页信息
     * @param $astrInfo
     * @param int $type 1=>获取用户端咨询师主页信息  2=>获取咨询师端主页信息
     * @param int $appType 1=>准有好事 2=>准了
     * @return array
     * @throws \Exception
     */
    public function homePage($astrInfo, int $type = 1, int $appType = 1)
    {
        $zlcrTagModel = new ZlcrTag();
        $consultModel = new Zlcr3ConsultAccount();
        $workIntro = "";
        $serviceTime = "";
        if ($type === 1 && Util::ZyhsIsHuaweiOrHonorOrOppoHg($appType))
        {
            $rtcConfig = (new ZyhsConfig())->configInfo('rtc');
            if (Util::IsHuaweiAndOppo())
            {
                if (isset($rtcConfig['huawei_work_intro']) && $rtcConfig['huawei_work_intro'])
                {
                    $workIntro = $rtcConfig['huawei_work_intro'];
                }
            } else
            {
                if (isset($rtcConfig['honor_work_intro']) && $rtcConfig['honor_work_intro'])
                {
                    $workIntro = $rtcConfig['honor_work_intro'];
                }
            }
            if (isset($rtcConfig['huawei_service_time']) && $rtcConfig['huawei_service_time'])
            {
                $serviceTime = $rtcConfig['huawei_service_time'];
            }
        }
        if (empty($workIntro))
        {
            $workIntro = $astrInfo['extend']['work_intro'] ?? '';
        }
        if (empty($serviceTime))
        {
            $serviceTime = $astrInfo['extend']['service_time'] ?? '';
        }
        //咨询标签
        $consultInfo = $consultModel->getInfoById($astrInfo['id']);
        if ($consultInfo)
        {
            $consultTids = $consultInfo['tids'];
            if (!empty($consultTids))
            {
                $tagsIcon = $zlcrTagModel->batchGetInfoByIds($consultTids, ['templet_url']);
                $tagsIcon = array_column($tagsIcon, 'templet_url');
            } else
            {
                $tagsIcon = [];
            }
            $tags = [];
            if ($consultInfo['tags'])
            {
                $tags = $consultModel->getTags($consultInfo['tags']);
            }
            if ($type === 1)
            {
                $price = $consultInfo['price'];
            } else
            {   // 单价转换 成 元    该单价 不包含 活动折扣
                $price = sprintf('%.2f', $consultInfo['price'] * $consultModel->getPercent($consultInfo['percent'], 1) / 10);
            }

            $res = [
                'name' => $astrInfo['nickname'],
                'avatar' => $astrInfo['avatar'],
                'tags_icon' => $tagsIcon,
                'tags' => $tags,
                'des' => $workIntro,
                'service_nums' => (int)ceil($consultInfo['service_duration'] / 60),
                'recommended_nums' => $consultInfo['recommended_nums'], // 页面显示推荐次数 可支持基数
                'server_info' => [
                    'title' => $consultInfo['service_title'] ?? '',
                    'chat_price' => $price,
                    'list' => [],
                ],
                'intro_info' => [
                    'title' => '资历介绍',
                    'des' => $astrInfo['extend']['qualification']['content'] ?? '',
                    'img_list' => $astrInfo['extend']['qualification']['pic_list'] ?? [],
                ],
                'status' => $consultInfo['status'] === 1 ? 1 : 0,
                'level' => $consultInfo['level'],
                'truth_recommend_num' => $consultInfo['recommended_nums'],  // ------打点新增 真实推荐次数
            ];
        } else
        {
            $res = [
                'name' => $astrInfo['nickname'],
                'avatar' => $astrInfo['avatar'],
                'tags_icon' => [],
                'tags' => [],
                'des' => $workIntro,
                'service_nums' => 0,
                'recommended_nums' => 0,
                'server_info' => null,
                'intro_info' => [
                    'title' => '资历介绍',
                    'des' => $astrInfo['extend']['qualification']['content'] ?? '',
                    'img_list' => $astrInfo['extend']['qualification']['pic_list'] ?? [],
                ],
                'status' => -1,
                'level' => 0,
            ];
        }

        if ($res['server_info'])
        {
            if (!empty($consultInfo['service_type']))
            {
                $res['server_info']['list'][] = '咨询方式：' . $consultInfo['service_type'];
            }
            if (!empty($serviceTime))
            {
                $res['server_info']['list'][] = '服务时间：' . $serviceTime;
            }
            if ($astrInfo['media_intro']['type'])
            {
                $res['server_info']['intro_data'] = $astrInfo['media_intro'];
            } else
            {
                $res['server_info']['intro_data'] = null;
            }
            if ($type === 1 && Util::AppIsPassShowV1())
            {   //  用户端   并且 合规情况 不显示
                $res['server_info']['intro_data'] = null;
            }
        }

        $res['is_can_appointment'] = $this->getAstrAppointmentStatus($astrInfo['id']);//默认隐藏预约按钮
        return $res;
    }

    /**
     * 主页信息
     * @param $astrInfo
     * @param int $type 1=>获取用户端咨询师主页信息  2=>获取咨询师端主页信息
     * @param int $appType 1=>准有好事 2=>准了
     * @return array
     * @throws \Exception
     */
    public function homePage2($astrInfo, int $type = 1, int $appType = 1)
    {
        $zlcrTagModel = new ZlcrTag();
        $consultModel = new Zlcr3ConsultAccount();
        $workIntro = "";
        $serviceTime = "";
        if ($type === 1 && Util::ZyhsIsHuaweiOrHonorOrOppoHg($appType))
        {
            $rtcConfig = (new ZyhsConfig())->configInfo('rtc');
            if (Util::IsHuaweiAndOppo())
            {
                if (isset($rtcConfig['huawei_work_intro']) && $rtcConfig['huawei_work_intro'])
                {
                    $workIntro = $rtcConfig['huawei_work_intro'];
                }
            } else
            {
                if (isset($rtcConfig['honor_work_intro']) && $rtcConfig['honor_work_intro'])
                {
                    $workIntro = $rtcConfig['honor_work_intro'];
                }
            }
            if (isset($rtcConfig['huawei_service_time']) && $rtcConfig['huawei_service_time'])
            {
                $serviceTime = $rtcConfig['huawei_service_time'];
            }
        }
        if (empty($workIntro))
        {
            $workIntro = $astrInfo['extend']['work_intro'] ?? '';
        }
        if (empty($serviceTime))
        {
            $serviceTime = $astrInfo['extend']['service_time'] ?? '';
        }
        //咨询标签
        $consultInfo = $consultModel->getInfoById($astrInfo['id']);
        if ($consultInfo)
        {
            $consultTids = $consultInfo['tids'];
            if (!empty($consultTids))
            {
                $tagsIcon = $zlcrTagModel->batchGetInfoByIds($consultTids, ['templet_url']);
                $tagsIcon = array_column($tagsIcon, 'templet_url');
            } else
            {
                $tagsIcon = [];
            }
            if ($type === 1)
            {
                $price = $consultInfo['price'];
            } else
            {   // 单价转换 成 元    该单价 不包含 活动折扣
                $price = sprintf('%.2f', $consultInfo['price'] * $consultModel->getPercent($consultInfo['percent'], 1) / 10);
            }
            $tagData = [];
            $zoneArr = [];
            $zoneList = Config::Load(APP_PATH . 'zyhsapi/extra/consult_zone.php', 'consult_zone', 'zyhs');;
            foreach ($zoneList as $zone)
            {
                if ($zone['status'] && in_array($zone['type'], $consultInfo['zone_tids'], true))
                {
                    $zoneArr[] = $zone['name'];
                    if (count($zoneArr) >= 2)
                    {
                        break;
                    }
                }
            }
            if ($zoneArr)
            {
                $tagData[] = '擅长：' . implode(' ', $zoneArr);
            }
            $tagsArr = $consultModel->getTags($consultInfo['tags']);
            if ($tagsArr && Util::ZyhsIsHuaweiOrHonorOrOppoHg($appType))
            {
                $tagsArr = array_values(array_diff($tagsArr, ['星盘']));
            }
            if (request()->header('app-type') === 'android')
            {
                foreach ($tagsArr as $k => $tagItem)
                {
                    if ($tagItem === '星盘')
                    {
                        $tagsArr[$k] = '星图';
                    }
                }
            }
            if ($tagsArr)
            {
                $tagData[] = '技能：' . implode(' ', $tagsArr);
            }
            $ActiveReplyNumData = (new ZlcrAstrConsultActiveReplyRecord())->getActiveReplyData();
            $res = [
                'name' => $astrInfo['nickname'],
                'avatar' => $astrInfo['avatar'],
                'tags_icon' => $tagsIcon,
                'tags' => $tagData,
                'des' => $workIntro,
                'service_nums' => (int)ceil($consultInfo['service_duration'] / 60),
                'recommended_nums' => $consultInfo['recommended_nums'], // 页面显示推荐次数 可支持基数
                'server_info' => [
                    'content' => $serviceTime,
                    'chat_price' => $price,
                ],
                'intro_info' => [
                    'title' => '资历介绍',
                    'des' => $astrInfo['extend']['qualification']['content'] ?? '',
                    'img_list' => $astrInfo['extend']['qualification']['pic_list'] ?? [],
                    'intro_data' => null,
                ],
                'status' => $consultInfo['status'] === 1 ? 1 : 0,
                'level' => $consultInfo['level'],
                'case_data' => [
                    'tip' => '所有案例在获得用户同意后公开 严格保护隐私',
                    'list' => (new ZyhsGoodRtcLiveMedia())->getAstrCaseList($astrInfo['id']),
                    'sts_sign' => (new AliyunVOD())->getStsToken(request()->header('app-type', 'astro'), 3600),
                ],
                'truth_recommend_num' => $consultInfo['recommended_nums'],  // ------打点新增 真实推荐次数
                'quick_reply_num' => $ActiveReplyNumData[$astrInfo['id']] ?? 0, // 积极回复数量
            ];
            if ($astrInfo['media_intro']['type'])
            {
                $res['intro_info']['intro_data'] = $astrInfo['media_intro'];
            }
            if ($type === 1 && Util::AppIsPassShowV1())
            {   //  用户端   并且 合规情况 不显示
                $res['intro_info']['intro_data'] = null;
            }
        } else
        {
            $res = [
                'name' => $astrInfo['nickname'],
                'avatar' => $astrInfo['avatar'],
                'tags_icon' => [],
                'tags' => [],
                'des' => $workIntro,
                'service_nums' => 0,
                'recommended_nums' => 0,
                'server_info' => null,
                'intro_info' => [
                    'title' => '资历介绍',
                    'des' => $astrInfo['extend']['qualification']['content'] ?? '',
                    'img_list' => $astrInfo['extend']['qualification']['pic_list'] ?? [],
                ],
                'status' => -1,
                'level' => 0,
                'case_data' => null,
                'quick_reply_num' => 0,
            ];
        }

        $res['is_can_appointment'] = $this->getAstrAppointmentStatus($astrInfo['id']);//默认隐藏预约按钮
        return $res;
    }

    /**
     * 获取咨询师近三天能否预约的状态
     * @param $astrId
     * @return bool
     * @throws \Exception
     */
    public function getAstrAppointmentStatus($astrId)
    {
        $isCanAppointment = false;//默认隐藏预约按钮 , 不能预约
        $astrDateRestList = (new Zl8AstrChatBusyDateRecord())->getAstrDateBusyList($astrId);
        if ($astrDateRestList)
        {
            $isDayOff = $this->isDayOffInNextThreeDays($astrDateRestList);
            $isCanAppointment = !$isDayOff;//咨询师三天都休息,则隐藏预约按钮
        } else
        {
            $astrRestList = (new Zl8AstrChatBusyRecord())->getAstrChatBusyList($astrId);
            if ($astrRestList)
            {
                $isCanAppointment = true;
            }
        }
        return $isCanAppointment;
    }

    /**检查最近三天是否为休息日
     * @param $daysOff
     * @return bool
     */
    private function isDayOffInNextThreeDays($daysOff)
    {
        $today = date('Ymd'); // 获取今天的日期
        $nextThreeDays = [];

        // 计算未来三天的日期
        for ($i = 0; $i <= 2; $i++)
        {
            $nextDay = date('Ymd', strtotime("+$i day", strtotime($today)));
            $nextThreeDays[] = $nextDay;
        }

        $res = array_diff($nextThreeDays, $daysOff);
        return !$res;
    }

    /**
     * @param int $type 1=>获取定制报告接单中的占星师ID 2=>获取定制报告回答中的占星师ID
     * @return array|mixed
     * @throws \Exception
     */
    public function astrIds(int $type)
    {
        return CacheManage::getInstance()->setCacheConfig($this->cacheModel, $type)->setCacheKeyDetail('astr_ids', $type)->ZsGetIocData('astr_ids', function () use ($type)
        {
            if ($type === 1)
            {
                $ids = $this->where('custom_report_status', 1)->column('id');
            }
            if ($type === 2)
            {
                $ids = (new ZlcrCustomReportQuestion())->where(['status' => ['in', [3, 4, 13]]])->column('astr_id');
            }
            if (isset($ids))
            {
                return array_flip_key_value($ids);
            }
            return [];
        });
    }
}
